Javalin 是個輕量型框架,在本範例程式中已有基本設定。請開啟Bootstrap.kt
,最後一段
@WebServlet(urlPatterns = ["/rest/*"], name = "JavalinRestServlet", asyncSupported = false)
class JavalinRestServlet : HttpServlet() {
val javalin: JavalinServlet = Javalin.createStandalone()
.configureRest()
.servlet()
override fun service(req: HttpServletRequest, resp: HttpServletResponse) {
javalin.service(req, resp)
}
}
fun Javalin.configureRest(): Javalin {
val gson: Gson = GsonBuilder().create()
gson.configureToJavalin()
return this
}
伺服器提供REST服務,而設定皆在 configureRest()
extension function
StudentRest.kt
package com.example.vok
import io.javalin.Javalin
import io.javalin.http.NotFoundResponse
fun Javalin.studentRest(){
get("/rest/student/:id"){ ctx ->
val id = ctx.pathParam("id").toLong()
Student.findById(id)?.let { ctx.json(it) }?: throw NotFoundResponse("No student with id:$id")
}
get("/rest/students"){ctx ->
ctx.json(Student.findAll())
}
get("/rest/student/:id/grade"){ctx->
val id = ctx.pathParam("id").toLong()
val student = Student.findById(id) ?: throw NotFoundResponse("No student with id:$id")
ctx.json(student.grades.fetch())
}
}
configureRest()
設定提供上述apifun Javalin.configureRest(): Javalin {
val gson: Gson = GsonBuilder().create()
gson.configureToJavalin()
studentRest()
return this
}
執行程式結果如下
看似已經提供了json格式rest api,但實務應用時,某些欄位並不提供給外部讀取,該怎麼做呢?
在configureRest()
方法中已設定由Gson處理物件和json的轉換,所以可採用Gson所提供的功能,設定哪些欄位需要序列化。
Student.kt
在需要輸出為Json的欄位前加上 annotation @Expose,例 @Expose
var name: String? = null
Boostrap.kt
修改 configureRest()
加上 excludeFieldsWithoutExposeAnnotation()方法fun Javalin.configureRest(): Javalin {
val gson: Gson = GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create()
gson.configureToJavalin()
studentRest()
return this
}
上述birthday 輸出為 "birthday":{"year":2001,"month":3,"day":13}
,筆者希望可轉成"birthday":"2001-03-13"
class LocalDateAdapter: JsonSerializer<LocalDate>{
override fun serialize(date: LocalDate, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement =
JsonPrimitive(date.format(DateTimeFormatter.ISO_LOCAL_DATE))
}
val gson: Gson = GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapter(LocalDate::class.java, LocalDateAdapter())
.excludeFieldsWithoutExposeAnnotation()
.create()
setPrettyPrinting() 將json格式為較易閱讀模式
registerTypeAdapter() 告訴GsonBuilder,只要遇到資料型態為LocalDate,就使用LocalDateAdapter()轉換